package org.example;

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;

import java.io.IOException;
import java.util.*;

public class HBaseTool extends Application {
    private Connection conn;
    private Admin admin;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        VBox root = new VBox(10);
        root.setPrefSize(600, 400);

        // 表名列表
        ListView<String> tableListView = new ListView<>();
        Button refreshButton = new Button("刷新表列表");
        Button queryButton = new Button("查询表数据");
        Button sizeButton = new Button("查看表大小");

        refreshButton.setOnAction(event -> {
            try {
                List<String> tableNames = listTables();
                tableListView.setItems(FXCollections.observableArrayList(tableNames));
            } catch (IOException e) {
                showError("刷新表列表失败", e.getMessage());
            }
        });

        queryButton.setOnAction(event -> {
            String selectedTable = tableListView.getSelectionModel().getSelectedItem();
            if (selectedTable != null) {
                showQueryDialog(selectedTable);
            } else {
                showError("错误", "请先选择一个表");
            }
        });

        sizeButton.setOnAction(event -> {
            String selectedTable = tableListView.getSelectionModel().getSelectedItem();
            if (selectedTable != null) {
                try {
                    long tableSize = getTableSize(selectedTable);
                    showInfo("表大小", "表 " + selectedTable + " 的大小为: " + tableSize + " bytes");
                } catch (IOException e) {
                    showError("获取表大小失败", e.getMessage());
                }
            } else {
                showError("错误", "请先选择一个表");
            }
        });

        root.getChildren().addAll(refreshButton, tableListView, queryButton, sizeButton);

        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.setTitle("HBase 小工具");
        primaryStage.show();
    }

    private List<String> listTables() throws IOException {
        conn = HBasePoolUtils.getConnection();
        admin = conn.getAdmin();
        TableName[] tableNames = admin.listTableNames();
        List<String> result = new ArrayList<>();
        for (TableName tableName : tableNames) {
            result.add(tableName.getNameAsString());
        }
        return result;
    }

    private long getTableSize(String tableName) throws IOException {
        conn = HBasePoolUtils.getConnection();
        admin = conn.getAdmin();
        TableName table = TableName.valueOf(tableName);
        List<HRegionInfo> regions = admin.getTableRegions(table);
        long totalSize = 0;
        for (HRegionInfo region : regions) {
            // Placeholder logic for region size calculation
            totalSize += region.getRegionName().length; // Adjust based on your setup
        }
        return totalSize;
    }

    private void showQueryDialog(String tableName) {
        Dialog<String> queryDialog = new Dialog<>();
        queryDialog.setTitle("查询表数据");
        queryDialog.setHeaderText("查询表 " + tableName + " 的数据");

        TextField rowKeyField = new TextField();
        rowKeyField.setPromptText("请输入主键");

        TextField splitNumField = new TextField();
        splitNumField.setPromptText("请输入分区数");

        ButtonType queryButtonType = new ButtonType("查询", ButtonBar.ButtonData.OK_DONE);
        queryDialog.getDialogPane().getButtonTypes().addAll(queryButtonType, ButtonType.CANCEL);

        VBox content = new VBox(10, new Label("Row Key:"), rowKeyField, new Label("分区数:"), splitNumField);
        queryDialog.getDialogPane().setContent(content);

        queryDialog.setResultConverter(button -> {
            if (button == queryButtonType) {
                String rowKey = rowKeyField.getText();
                int splitNum = Integer.parseInt(splitNumField.getText());
                String partitionedRowKey = getRowKey(rowKey, splitNum);
                try {
                    Map<String, String> result = HBaseMain.getMapResultByRowKey(tableName, partitionedRowKey);
                    showResultDialog(result);
                } catch (Exception e) {
                    showError("查询失败", e.getMessage());
                }
            }
            return null;
        });

        queryDialog.showAndWait();
    }

    private void showResultDialog(Map<String, String> result) {
        Dialog<Void> resultDialog = new Dialog<>();
        resultDialog.setTitle("查询结果");
        resultDialog.setHeaderText("查询结果如下:");

        TableView<Map.Entry<String, String>> resultTable = new TableView<>();
        TableColumn<Map.Entry<String, String>, String> columnNameCol = new TableColumn<>("列名");
        TableColumn<Map.Entry<String, String>, String> columnValueCol = new TableColumn<>("值");

        columnNameCol.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getKey()));
        columnValueCol.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getValue()));

        resultTable.getColumns().addAll(columnNameCol, columnValueCol);
        resultTable.getItems().addAll(result.entrySet());

        resultDialog.getDialogPane().setContent(resultTable);
        resultDialog.getDialogPane().getButtonTypes().add(ButtonType.OK);
        resultDialog.showAndWait();
    }

    private String getRowKey(String rowKey, int splitNum) {
        int rang = Math.abs(rowKey.hashCode() % splitNum);
        return SplitUtil.fillWithZero(String.valueOf(rang), 2) + "_" + rowKey;
    }

    private void showError(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }

    private void showInfo(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }
}